package com.weixin.controller;


import java.io.*;
import java.net.URLEncoder;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.weixin.config.WeiXinProperties;

import com.weixin.util.CommonInputStreamResource;
import com.weixin.util.RedisUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.*;

import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.File;

/**
 * @author zjd
 * @Title:
 * @Description:
 * @date 2021/4/1317:47
 */
@Api("企业素材文件")
@RestController
@RequestMapping("/v1.0/wei-xin/cgi-bin/media")
public class FileController {

    @Autowired
    private RestTemplate restTemplate;
    @Resource
    private ObjectMapper objectMapper;

    @Autowired
    private RedisUtil redisUtil;


    /**
     * 使用这种方式的好处就是写起来比较简单,缺点是会在项目根路径下生成一个临时文件,上传成功之后你需要将生成的临时文件删除掉
     * */
    @ApiOperation("上传临时文件")
    @PostMapping("/uploadFile")
    public  ResponseEntity uploadFile(MultipartFile upfile, String type, HttpSession session) throws Exception {
        StringBuilder urlBuilder=new StringBuilder(WeiXinProperties.getUrl());
        urlBuilder.append("cgi-bin/media/upload?");
        String access_token =(String) session.getAttribute("access_token_application");
        urlBuilder.append("access_token="+access_token);
        urlBuilder.append("&type="+type);
       // 构建请求头
        HttpHeaders requestHeaders = new HttpHeaders();
        requestHeaders.add("appCode", "platform-device");
        requestHeaders.setContentType(MediaType.MULTIPART_FORM_DATA);
        // 构建请求体
        MultiValueMap<String, Object> requestBody = new LinkedMultiValueMap<>();
        // 获取文件名
        String fileName = upfile.getOriginalFilename();
        Assert.notNull(fileName,"获取上传的原始文件名不能为空");
        File file = new File(fileName);
        try (OutputStream out = new FileOutputStream(file)) {
            // 输入流和输出流之间的拷贝
            FileCopyUtils.copy(upfile.getInputStream(),out);
        } catch (IOException e) {
            System.out.println("上传的文件转换异常" + e.getMessage());
        }
        //从File句柄创建一个新的FileSystemResource
        FileSystemResource resource = new FileSystemResource(file);
        requestBody.add("media", resource);

        // 发送上传请求
        HttpEntity<MultiValueMap> requestEntity = new HttpEntity<MultiValueMap>(requestBody, requestHeaders);
        //ResponseEntity<HashMap> responseEntity = restTemplate.postForEntity("你的文件上传路径",requestEntity, HashMap.class);
        String result = restTemplate.postForObject(urlBuilder.toString(),requestEntity, String.class);
        Map<String, Object> readValue = objectMapper.readValue(result, HashMap.class);
        return resultMap(readValue,1,null);

    }

    @ApiOperation("上传图片文件")
    @PostMapping("/uploadImg")
    public  ResponseEntity uploadImg(MultipartFile upfile, HttpSession session) throws Exception {
        StringBuilder urlBuilder=new StringBuilder(WeiXinProperties.getUrl());
        urlBuilder.append("cgi-bin/media/uploadimg?");
        String access_token =(String) session.getAttribute("access_token_application");
        urlBuilder.append("access_token="+access_token);
        // 构建请求头
        HttpHeaders requestHeaders = new HttpHeaders();
        requestHeaders.add("appCode", "platform-device");
        requestHeaders.setContentType(MediaType.MULTIPART_FORM_DATA);
        // 构建请求体
        MultiValueMap<String, Object> requestBody = new LinkedMultiValueMap<>();
        // 获取文件名
        String fileName = upfile.getOriginalFilename();
        Assert.notNull(fileName,"获取上传的原始文件名不能为空");
        CommonInputStreamResource commonInputStreamResource = null;
        try  {
            commonInputStreamResource = new CommonInputStreamResource(upfile.getInputStream(),upfile.getSize(),upfile.getOriginalFilename());
        } catch (IOException e) {
            System.out.println("上传的文件转换异常" + e.getMessage());
        }

        requestBody.add("name", commonInputStreamResource);

        // 发送上传请求
        HttpEntity<MultiValueMap> requestEntity = new HttpEntity<MultiValueMap>(requestBody, requestHeaders);
        //ResponseEntity<HashMap> responseEntity = restTemplate.postForEntity("你的文件上传路径",requestEntity, HashMap.class);
        String result = restTemplate.postForObject(urlBuilder.toString(),requestEntity, String.class);
        Map<String, Object> readValue = objectMapper.readValue(result, HashMap.class);
        return resultMap(readValue,1,null);
    }


    @ApiOperation("下载临时文件")
    @GetMapping("{mediaId}/download")
    public void download(@PathVariable("mediaId")String mediaId , HttpServletResponse response) throws IOException {
        StringBuilder urlBuilder=new StringBuilder(WeiXinProperties.getUrl());
        urlBuilder.append("cgi-bin/media/get?");
        String access_token =(String) redisUtil.get("access_token_application");
        urlBuilder.append("access_token="+access_token);
        urlBuilder.append("&media_id="+mediaId);

        HttpHeaders headers = new HttpHeaders();
        headers.setAccept(Collections.singletonList(MediaType.TEXT_HTML));
        HttpEntity<String> entity = new HttpEntity<>(headers);

        ResponseEntity<byte[]> exchange = restTemplate.exchange(urlBuilder.toString(), HttpMethod.GET, entity, byte[].class);

        HttpHeaders headers1 = exchange.getHeaders();
        headers1.getContentType().toString();
        response.setHeader("Content-Type",  headers1.getContentType().toString());
        response.setHeader("Content-Disposition",  headers1.getContentDisposition().toString());
        response.setHeader("Date", String.valueOf(headers1.getDate()));
        response.setHeader("Cache-Control",  headers1.getCacheControl());
        response.setHeader("Content-Length", String.valueOf(headers1.getContentLength()));
        //getOutputStream引擎创建的字节输出流对象
        response.getOutputStream().write(exchange.getBody());

    }


    private ResponseEntity resultMap(Map<String, Object> resultMap, Integer type, String key){
        for (Map.Entry<String, Object> entry : resultMap.entrySet()) {
            if (entry.getKey().equals("errcode")){
                Integer integer = (Integer) resultMap.get("errcode");
                if (integer==0){
                    ResponseEntity responseEntity = type==0 ? new ResponseEntity(resultMap.get(key), HttpStatus.OK): new ResponseEntity(resultMap, HttpStatus.OK);
                    return responseEntity;
                }
            }
        }
        return new ResponseEntity(resultMap,HttpStatus.INTERNAL_SERVER_ERROR);
    }

}
